# -*- coding: utf-8 -*-
""" Auteur: Félix Cloutier """
import TextualAnalysis
import re
import tkMessageBox
from Tkinter import *

""" Cette classe donne des objets temporaires pour couvrir:
    - un "range" de texte (début et fin)
    - une couleur à associer au texte (en vertu des couleurs d'analysisColors).
"""
class ColorTag(object):
    def __init__(self, start, end, color):
        self.start = start
        self.end = end
        self.color = color
    
    def __lt__(self, obj):
        return self.begin < obj.begin

""" Couleurs des mots-clé """
analysisColors = {TextualAnalysis.VERB: "darkred", TextualAnalysis.ADJECTIVE: "darkblue", TextualAnalysis.NOUN: "darkgreen"}
""" variable globale pour le client """
client = None

""" Cette classe sert à gérer l'interface graphique associée au mandat et à l'analyse textuelle.
    Il est possible d'y écrire le mandat et de sélectionner ensuite les mots-clé dans l'analyse.
    Collaborateurs:
        L'objet client
        L'objet d'analyse textuelle
        Les objets d'interface de Tkinter
    Responsabilités:
        colorTags(event)
        save()
        addVerb()
        addNoun()
        addAdjective()
        removeKeyword()
        addKeyword(name, type)
        highlight(keyword, type)
        unhighlight(keyword, type)
        keywordWithName(name)
"""
class TextualAnalysisInterface:
    def __init__(self,client):
        self.client = client
        self.window = Toplevel(width = 600, height = 500)
        self.textfield = Text(self.window, width = 100, height = 20)
        self.textualAnalysis = client.server.getObjectsOfClass(TextualAnalysis.TextualAnalysis)
        if len(self.textualAnalysis) == 0:
            self.textualAnalysis = TextualAnalysis.TextualAnalysis()
        else:
            self.textualAnalysis = self.textualAnalysis[0]
        
        text = self.textualAnalysis.text
        
        for color in analysisColors.itervalues():
            self.textfield.tag_config(color, foreground = color, underline = 1)
        
        self.textfield.insert("1.0", text)
        
        for keyword in self.textualAnalysis.keyWords:
            self.highlight(keyword.keyWord, keyword.type)
        
        self.textfield.grid(row=0, column=0, columnspan=3)
        self.textfield.bind("<KeyRelease>", self.colorTags)
        Button(self.window, text = "Verbe", command = self.addVerb).grid(row=1, column=0, sticky=E)
        Button(self.window, text = "Adjectif", command = self.addAdjective).grid(row=1, column=1)
        Button(self.window, text = "Nom", command = self.addNoun).grid(row=1, column=2, sticky=W)
        
        Button(self.window, text = "Retirer", command = self.removeKeyword).grid(row=2, column=0, sticky=W)
        Button(self.window, text = "Sauvegarder", command = self.save).grid(row=2, column=2, sticky=E)
    
    """ colorie l'analyse textuelle.
        Cette méthode est appelée chaque fois qu'une touche est tapée, pour mettre
        à jour les couleurs en temps réel. """
    def colorTags(self, event):
        text = self.textfield
        
        position = text.index(INSERT)
        start = text.index("insert - 1c wordstart")
        end = text.index("insert - 1c wordend")
        
        word = text.get(start, end).strip()
        for color in analysisColors.itervalues():
            self.textfield.tag_remove(color, start, end)
        
        for keyword in self.textualAnalysis.keyWords:
            if word.lower() == keyword.keyWord.lower():
                text.delete(start, end)
                text.insert(start, word, analysisColors[keyword.type])
                text.mark_set(INSERT, position)
                break
    
    """ Sauvegarde les données. """
    def save(self):
        self.textualAnalysis.text = self.textfield.get("1.0", END)
        self.textualAnalysis = client.server.setObject(self.textualAnalysis)
    
    """ Ces trois méthodes créent un mot-clé d'un certain type.
        voir addKeyword. """
    def addVerb(self):
        self.addKeyword(TextualAnalysis.VERB)
    def addNoun(self):
        self.addKeyword(TextualAnalysis.NOUN)
    def addAdjective(self):
        self.addKeyword(TextualAnalysis.ADJECTIVE)
    
    """ Cette méthode retire un mot-clé de l'objet d'analyse textuelle et le décolore
        dans toutes ses apparitions dans le texte. """
    def removeKeyword(self):
        text = self.textfield
        position = text.index(INSERT)
        start = text.index("insert - 1c wordstart")
        end = text.index("insert - 1c wordend")
        word = text.get(start, end).strip()
        keyword = self.keywordWithName(word)
        keyword.unlink()
        self.unhighlight(word, keyword.type)
        self.textualAnalysis.keyWords.remove(keyword)
    
    """ Cette méthode ajoute un mot-clé et le colore dans toutes ses apparitions dans le mandat. """
    def addKeyword(self, type):
        text = self.textfield
        start = text.index("insert - 1c wordstart")
        end = text.index("insert - 1c wordend")
        keyword = text.get(start, end)
        if not keyword.isspace():
            self.textualAnalysis.keyWords.append(TextualAnalysis.KeyWord(keyword, type))
            self.highlight(keyword, type)
    
    """ Cette méthode colore un mot-clé. Elle est appelée par addKeyword. """
    def highlight(self, keyword, type):
    	position = self.textfield.index(INSERT)
        text = self.textfield.get("1.0", END)
        regex = re.compile(r"\b%s\b" % keyword, re.IGNORECASE)
        for match in regex.finditer(text):
            start = "1.0 + %ic" % match.start()
            end = "1.0 + %ic" % match.end()
            self.textfield.tag_add(analysisColors[type], start, end)
        self.textfield.mark_set(INSERT, position)
    
    """ Cette méthode décolore un mot-clé. Elle est appelée par removeKeyword. """
    def unhighlight(self, keyword, type):
        position = self.textfield.index(INSERT)
        text = self.textfield.get("1.0", END)
        regex = re.compile(r"\b%s\b" % keyword, re.IGNORECASE)
        for match in regex.finditer(text):
            start = "1.0 + %ic" % match.start()
            end = "1.0 + %ic" % match.end()
            self.textfield.tag_remove(analysisColors[type], start, end)
        self.textfield.mark_set(INSERT, position)
    
    """ Cette méthode retourne l'objet KeyWord associé à un mot-clé (string) donné. """
    def keywordWithName(self, word):
        for keyword in self.textualAnalysis.keyWords:
            if keyword.keyWord == word:
                return keyword
        return None

""" Cette fonction sert à connecter la classe à l'interface graphique globale. """
def PlugIn(objClient):
    global client
    client = objClient
    Button(client.frame, text = "Analyse textuelle", command = analysis).pack()

def analysis():
    TextualAnalysisInterface(client)